package susebs.pb.travel_server.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import susebs.pb.travel_server.domain.PageDto;
import susebs.pb.travel_server.entity.Comments;
import susebs.pb.travel_server.entity.Orders;
import susebs.pb.travel_server.dao.OrdersDao;
import susebs.pb.travel_server.entity.Packages;
import susebs.pb.travel_server.entity.Users;
import susebs.pb.travel_server.service.*;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 订单表(Orders)表服务实现类
 *
 * @author makejava
 * @since 2024-02-05 08:02:27
 */
@Service("ordersService")
public class OrdersServiceImpl implements OrdersService {
    @Resource
    private OrdersDao ordersDao;
    @Resource
    private LandmarksService landmarksService;
    @Resource
    private HotelsService hotelsService;
    @Resource
    private PackagesService packagesService;
    @Resource
    private UsersService usersService;
    @Resource
    private CommentsService commentsService;
    @Resource
    private LandmarkPackageService landmarkPackageService;
    @Resource
    private HotelPackageService hotelPackageService;

    /**
     * 通过ID查询单条数据
     *
     * @param orderId 主键
     * @return 实例对象
     */
    @Override
    public Orders queryById(Long orderId) {
        return this.ordersDao.queryById(orderId);
    }


    /**
     * 分页查询
     *
     * @param orders      筛选条件
     * @param pageRequest 分页对象
     * @return 查询结果
     */
    @Override
    public Page<Orders> queryByPage(Orders orders, PageRequest pageRequest) {
        long total = this.ordersDao.count(orders);
        return new PageImpl<>(this.ordersDao.queryAllByLimit(orders, pageRequest), pageRequest, total);
    }


    /**
     * pageHelper进行分页查询
     * @param pageDto
     * @return
     */
    @Override
    public PageInfo queryAllOrdersByPage(PageDto pageDto) {
        //空值处理
        if(pageDto.getPage() == null || pageDto.getSize() == null){
            pageDto.setPage(1);
            pageDto.setSize(10);
        }
        PageHelper.startPage(pageDto.getPage(), pageDto.getSize(),"order_create_time desc");
        List<Orders> list = ordersDao.queryAllOrders(pageDto.getOrders());
        PageInfo<Orders> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }


    /**
     * 用户下单（新增数据）
     * 业务逻辑：
     * 1.根据交易类型（transaction_type）生成商户全称(acquirer)
     *      --景点 1 ：景点名(lm_name)+开发建设有限公司
     *      --套餐 2 ：直接取值套餐提供商（merchat_name）
     *      --酒店 3 ：酒店名（hotel_name）
     * 2.生成订单编号
     *      --使用随机数+时间戳+随机数组成
     * 3.折扣设置
     *      --折扣次数够用，则进行折扣且折扣次数-1
     * @param order 实例对象
     * @return 实例对象
     */
    @Override
    public Orders insert(Orders order) {
        //非空判断
        if(order.getTransactionType() == null){
            System.out.println("type is null!");
            return new Orders();
        }

        //订单名、商户全称
        if(order.getTransactionType() == 1){
            String name = landmarksService.queryById(order.getTransactionId()).getLmName();
            String param = name + "开发建设有限公司";
            order.setOrderName(name);
            order.setOrderMerchatName(param);
        }
        else if(order.getTransactionType() == 2){
            Packages packages = packagesService.queryById(order.getTransactionId());
            order.setOrderName(packages.getPkName());
            order.setOrderMerchatName(packages.getMerchatName());
        }
        else if(order.getTransactionType() == 3){
            String name = hotelsService.queryById(order.getTransactionId()).getHotelName() + "房间";
            order.setOrderName(name);
            order.setOrderMerchatName(name);
        }
        else{
            System.out.println("id is null!");
            return new Orders();
        }

        //订单编号
        Random random = new Random();
        LocalDate now = LocalDate.now();
        int prefixRandom = random.nextInt((9999 - 1000) + 1) + 1000;
        int suffixRandom = random.nextInt((99999 - 10000) + 1) + 10000;
        String date = now.format(DateTimeFormatter.ofPattern("yyMMdd"));
        String param = String.valueOf(prefixRandom) + date + String.valueOf(suffixRandom);
        order.setOrderNumber(param);

        //收单机构
        order.setAcquirer("大P支付科技有限公司");

        /**
         * 折扣逻辑
         * 先判断用户剩余折扣次数是否足够
         * 足够则进行折扣且用户折扣可用次数-1
         * 否则不予折扣并重置isDiscount为0
         * @return 处理完成的order实体，方便前端根据isDiscount的值给出提示“折扣成功/失败”
         */
        if(order.getIsDiscount() == 1){
            //查询用户剩余折扣次数
            Users user = usersService.queryById(order.getUserId());
            Integer discountTimes = user.getDiscountTimes();
            //折扣次数足够
            if(discountTimes > 0){
                order.setOrderTotalAmount(order.getOrderTotalAmount()*0.5);
                user.setDiscountTimes(discountTimes - 1);
                usersService.update(user);
            }
            //折扣次数不足
            else{
                order.setIsDiscount(0);
            }

        }

        //调用方法
        ordersDao.insert(order);
        return ordersDao.queryById(order.getOrderId());
    }


    /**
     * 修改数据
     *
     * @param orders 实例对象
     * @return 实例对象
     */
    @Override
    public Orders update(Orders orders) {
        this.ordersDao.update(orders);
        return this.queryById(orders.getOrderId());
    }


    /**
     * 通过主键删除数据
     *
     * @param orderId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long orderId) {
        return this.ordersDao.deleteById(orderId) > 0;
    }


    /**
     * 取消订单
     * status == 1
     * （如有）返还用户折扣次数
     */
    @Override
    public Orders cancelOrder(Long orderId) {
        //重置订单状态
        Orders order = this.queryById(orderId);
        order.setOrderStatus(1);

        //返还用户折扣次数
        if(order.getIsDiscount() == 1){
            Users user = usersService.queryById(order.getUserId());
            user.setDiscountTimes(user.getDiscountTimes() + 1);
            usersService.update(user);
        }

        //修改订单记录
        ordersDao.update(order);

        return order;
    }


    /**
     * 订单完成支付
     * status == 2
     */
    @Override
    public Orders completePayment(Long orderId) {
        //重置订单状态
        Orders order = this.queryById(orderId);
        order.setOrderStatus(2);

        //修改订单表
        ordersDao.update(order);
        return order;
    }


    /**
     * 用户退款
     * status == 3
     * （如有）则退还折扣次数
     */
    @Override
    public Orders cancelPayment(Long orderId) {
        //重置订单状态
        Orders order = this.queryById(orderId);
        order.setOrderStatus(3);

        //返还折扣次数
        Users user = usersService.queryById(order.getUserId());
        if(order.getIsDiscount() == 1){
            user.setDiscountTimes(user.getDiscountTimes() + 1);
            usersService.update(user);
        }

        //修改订单表
        ordersDao.update(order);
        return order;
    }


    /**
     * 订单完成
     * status == 5
     * 业务逻辑：
     * 1.修改订单表状态
     * 2.搜索订单表关联的实体，将其相关联的实体类型和id插入评论表（仅插入，未到评论环节），即数据预插入
     * 3.查询用户剩余折扣次数，折扣此时为0时修改其角色为2-大众会员
     */
    @Override
    public Orders completeOrder(Long orderId) {
        Comments comment;
        //重置订单状态
        Orders order = this.queryById(orderId);
        order.setOrderStatus(5);

        /**
         * 分情况查询订单关联实体
         * type：1，3直接插入
         * type：2，进入关联表(lm_pk,hotel_pk)查询所有关联到的实体id，之后再插入
         */
        if(order.getTransactionType() == 1 || order.getTransactionType() == 3){
            comment = new Comments();
            //非空判断
            if(order.getTransactionId() == null || order.getUserId() == null){
                System.out.println("id is null!");
                return new Orders();
            }
            //插入数据
            comment.setUserId(order.getUserId());
            comment.setRelatedEntityType(order.getTransactionType());
            comment.setRelatedEntityId(order.getTransactionId());
            commentsService.preInsert(comment);
        }
        else if(order.getTransactionType() == 2){
            comment = new Comments();
            //非空判断
            if(order.getTransactionId() == null || order.getUserId() == null){
                System.out.println("id is null!");
                return new Orders();
            }
            //寻找套餐关联实体id列表
            //关联的景点
            ArrayList<Long> LmsList = landmarkPackageService.queryAll(order.getTransactionId());
            //关联的酒店
            ArrayList<Long> hotelsList = hotelPackageService.queryAll(order.getTransactionId());

            //数据预插入
            comment.setUserId(order.getUserId());

            //套餐自身数据预插入
            comment.setRelatedEntityType(order.getTransactionType());
            comment.setRelatedEntityId(order.getTransactionId());
            commentsService.preInsert(comment);

            //关联景点数据预插入
            for (Long id:LmsList) {
                comment.setRelatedEntityType(1);
                comment.setRelatedEntityId(id);
                commentsService.preInsert(comment);
            }

            //关联酒店数据预插入
            for (Long id:hotelsList) {
                comment.setRelatedEntityType(3);
                comment.setRelatedEntityId(id);
                commentsService.preInsert(comment);
            }

        } else{
            System.out.println("type is null!");
            return new Orders();
        }

        //查询用户剩余折扣次数
        Users user = usersService.queryById(order.getUserId());
        if(user.getDiscountTimes() == 0){
            user.setRoleId(2L);
            usersService.update(user);
        }

        //修改订单表
        ordersDao.update(order);
        return order;
    }





}
